package com.woniuxy.yoga.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.yoga.commons.alipay.data.AlipayParam;
import com.woniuxy.yoga.commons.alipay.util.AlipayUtil;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.*;
import com.woniuxy.yoga.commons.redis.util.rediskeyutil.OrderRedisKeyUtil;
import com.woniuxy.yoga.order.client.*;
import com.woniuxy.yoga.order.dao.mapper.OrderInfoMapper;
import com.woniuxy.yoga.order.dao.model.OrderInfo;
import com.woniuxy.yoga.order.model.dto.*;
import com.woniuxy.yoga.order.model.exception.OrderException;
import com.woniuxy.yoga.order.model.exception.OrderExceptionCode;
import com.woniuxy.yoga.order.model.form.*;
import com.woniuxy.yoga.order.model.param.*;
import com.woniuxy.yoga.order.service.OrderInfoService;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private UserClient userClient;

    @Autowired
    private ProductClient productClient;

    @Autowired
    private BusinessClient businessClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AlipayUtil alipayUtil;

    @Autowired
    private ProgressClient progressClient;

    @Autowired
    private CoachClient coachClient;

    /**
     * 下单
     * @param param 下单参数
     * @return String
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public OrderInfoDto createOrder(CreateOrderParam param) {
        //判断用户
        Result<UserInfoDto> userInfoDtoResult = userClient.getByUserId(param.getUserId());
        if (userInfoDtoResult.getCode()!=200) throw new OrderException(userInfoDtoResult.getCode(),userInfoDtoResult.getMessage());
        //判断用户是否已完成实名认证
        if (userInfoDtoResult.getData().getIdCard()==null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_NO_IDCARD);
        //判断用户状态
        if (!Objects.equals(userInfoDtoResult.getData().getUserState(), UserState.USER_ACCOUNT_STATE_NORMAL))
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_USER_STATE_WRONG);
        UserInfoDto userInfoDto = userInfoDtoResult.getData();
        //判断体验课是否已经购买过或数量大于1
        if (Objects.equals(param.getProductTypeId(), OrderState.PRODUCT_TYPE_ID_EXPERIENCE)){
            Result<Expcard> expcardResult = progressClient.getExpCardByUserId(param.getUserId());
            if (expcardResult.getCode()!=90001) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_EXPERIENCE_ONCE);
            if (param.getOrderCount()>1)
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_NO_IDCARD);
        }
        //判断终身卡是否重复购买
        if (Objects.equals(param.getProductTypeId(), OrderState.PRODUCT_TYPE_ID_INFINITY)){
            Result<Lifecard> lifecardResult = progressClient.getLifeCardByUserId(param.getUserId());
            if (lifecardResult.getCode()!=90001) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_INFINITY_ONCE);
        }
        //创建订单对象
        OrderInfoDto orderInfoDto = new OrderInfoDto();
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userInfoDto.getUserId());
        orderInfo.setUserName(userInfoDto.getUserName());
        orderInfo.setTypes(param.getTypes());
        orderInfo.setOrderNum(new Snowflake(1,1).nextIdStr());
        orderInfo.setOrderCount(param.getOrderCount());
        orderInfo.setRemarks(param.getRemarks());
        //判断产品类型
        //1.普通课程产品
        if (Objects.equals(param.getTypes(), OrderState.ORDER_PRODUCT_TYPE_NORMAL)){
            Result<ProductByIdDTO> productDTOResult = productClient.getByProductId(param.getProductId());
            if (productDTOResult.getCode()!=200) throw new OrderException(productDTOResult.getCode(),productDTOResult.getMessage());
            //判断产品状态
            if (!Objects.equals(productDTOResult.getData().getProductState(), ProductState.PRODUCT_STATE_NORMAL))
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_PRODUCT_STATE_WRONG);
            ProductByIdDTO productByIdDTO = productDTOResult.getData();
            //查询产品所属门店
            Result<BusinessStore> businessStoreResult = businessClient.selByStoreId(productByIdDTO.getStoreId());
            if (businessStoreResult.getCode()!=200) throw new OrderException(businessStoreResult.getCode(),businessStoreResult.getMessage());
            //判断门店状态
            if (!Objects.equals(businessStoreResult.getData().getStoreState(), BusinessState.STORE_STATE_NORMAL))
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_STORE_STATE_WRONG);
            orderInfo.setStoreId(businessStoreResult.getData().getStoreId());
            orderInfo.setProductTypeId(param.getProductTypeId());
            orderInfo.setProductId(productByIdDTO.getProductId());
            orderInfo.setProductName(productByIdDTO.getProductName());
            BigDecimal total = productByIdDTO.getProductPrice().multiply(new BigDecimal(orderInfo.getOrderCount()));
            orderInfo.setOrderMoney(total);
        }
        //2.团课产品
        if (Objects.equals(param.getTypes(), OrderState.ORDER_PRODUCT_TYPE_TEAM)){
            Result<TeamProductByIdDTO> teamProductByIdDTOResult = productClient.getByTeamProductId(param.getProductId());
            if (teamProductByIdDTOResult.getCode()!=200)
                throw new OrderException(teamProductByIdDTOResult.getCode(),teamProductByIdDTOResult.getMessage());
            //判断产品状态
            if (!Objects.equals(teamProductByIdDTOResult.getData().getTeamProductState(), ProductState.TEAM_PRODUCT_STATE_WAIT))
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_TEAM_PRODUCT_STATE_WRONG);
            TeamProductByIdDTO teamProductByIdDTO = teamProductByIdDTOResult.getData();
            if (teamProductByIdDTO.getBookNum()>=teamProductByIdDTO.getHourCount()){
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_TEAM_COUNT_FULL);
            }else {
                Result<?> result = productClient.modifyBookNum(teamProductByIdDTO.getTeamProductId());
                if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
            }
            //查询产品所属门店
            Result<BusinessStore> businessStoreResult = businessClient.selByStoreId(teamProductByIdDTO.getStoreId());
            if (businessStoreResult.getCode()!=200) throw new OrderException(businessStoreResult.getCode(),businessStoreResult.getMessage());
            //判断门店状态
            if (!Objects.equals(businessStoreResult.getData().getStoreState(), BusinessState.STORE_STATE_NORMAL))
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_STORE_STATE_WRONG);
            orderInfo.setStoreId(businessStoreResult.getData().getStoreId());
            orderInfo.setProductTypeId(null);
            orderInfo.setProductId(teamProductByIdDTO.getTeamProductId());
            orderInfo.setProductName(teamProductByIdDTO.getTeamProductName());
            BigDecimal total = teamProductByIdDTO.getTeamProductPrice().multiply(new BigDecimal(orderInfo.getOrderCount()));
            orderInfo.setOrderMoney(total);
        }
        //3.私教产品
        if (Objects.equals(param.getTypes(), OrderState.ORDER_PRODUCT_TYPE_COACH)){
            Result<PrivateProductByIdDTO> privateProductByIdDTOResult = productClient.getByPrivateProductId(param.getProductId());
            if (privateProductByIdDTOResult.getCode()!=200)
                throw new OrderException(privateProductByIdDTOResult.getCode(),privateProductByIdDTOResult.getMessage());
            //判断状态
            if (!Objects.equals(privateProductByIdDTOResult.getData().getPrivateProductState(), ProductState.PRIVATE_PRODUCT_STATE_NORMAL))
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_PRIVAYE_PRODUCT_STATE_WRONG);
            PrivateProductByIdDTO privateProductByIdDTO = privateProductByIdDTOResult.getData();
            //查询产品所属门店
            Result<BusinessStore> businessStoreResult = businessClient.selByStoreId(privateProductByIdDTO.getStoreId());
            if (businessStoreResult.getCode()!=200) throw new OrderException(businessStoreResult.getCode(),businessStoreResult.getMessage());
            //判断门店状态
            if (!Objects.equals(businessStoreResult.getData().getStoreState(), BusinessState.STORE_STATE_NORMAL))
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_STORE_STATE_WRONG);
            //生成订单信息
            orderInfo.setStoreId(businessStoreResult.getData().getStoreId());
            orderInfo.setProductTypeId(null);
            orderInfo.setProductId(privateProductByIdDTO.getPrivateProductId());
            orderInfo.setProductName(privateProductByIdDTO.getPrivateProductName());
            BigDecimal total = privateProductByIdDTO.getPrivateProductPrice().multiply(new BigDecimal(orderInfo.getOrderCount()));
            orderInfo.setOrderMoney(total);
        }
        orderInfo.setOrderCreateTime(DateUtil.format(new Date(System.currentTimeMillis()),"yyyy-MM-dd HH:mm:ss"));
        orderInfo.setOrderEvaluationState(OrderState.ORDER_EVALUATION_STATE_NO);
        orderInfo.setOrderState(OrderState.ORDER_STATE_NO_PAY);
        orderInfoMapper.insert(orderInfo);
        //生成订单日志数据（消息队列处理）
        Map<String, Object> logMap = new HashMap<>();
        logMap.put("orderNum",orderInfo.getOrderNum());
        logMap.put("logUser",userInfoDto.getUserName());
        logMap.put("storeId",orderInfo.getStoreId());
        logMap.put("logTime",DateUtil.format(new Date(System.currentTimeMillis()),"yyyy-MM-dd HH:mm:ss"));
        logMap.put("logDesc",userInfoDto.getUserName()+"在"+logMap.get("logTime")+"下单了课程");
        rabbitTemplate.convertAndSend("orderInfo.log",logMap);
        //设置未支付取消时间
        rabbitTemplate.convertAndSend("order-delay",orderInfo.getOrderNum());
        //生成订单数据返回
        orderInfoDto = BeanUtil.toBean(orderInfo, OrderInfoDto.class);
        return orderInfoDto;
    }

    /**
     * 订单支付
     * @param param 支付参数
     * @return String
     */
    @Override
    public String pagePay(OrderPagePayParam param) throws Exception {
        //对当前订单加锁
        RLock lock = redissonClient.getFairLock(OrderRedisKeyUtil.getOrderNumKey(param.getOrderNum()));
        try {
            if (lock.tryLock(10, TimeUnit.SECONDS)){
                //查询订单能否支付
                QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
                wrapper.eq("order_num",param.getOrderNum());
                OrderInfo orderInfo = orderInfoMapper.selectOne(wrapper);
                if (orderInfo == null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NOT_EXIST);
                if (!Objects.equals(orderInfo.getOrderState(), OrderState.ORDER_STATE_NO_PAY))
                    throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NO_PAY);
                //发起支付
                AlipayParam alipayParam = new AlipayParam();
                alipayParam.setBody(orderInfo.getProductName());
                alipayParam.setOutTradeNo(param.getOrderNum());
                alipayParam.setTotalAmount(orderInfo.getOrderMoney());
                alipayParam.setSubject("购买芦苇瑜伽课程产品");
                //同步回调
                alipayParam.setReturnUrl(param.getReturnUrl());
                //异步回调
                alipayParam.setNotifyUrl(AlipayUtil.NAT_APP_URL_LANG+"/order/orderInfo/orderNotify");
                return alipayUtil.payPage(alipayParam);
            }else {
                throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_SYSTEM_BUSY);
            }
        }finally {
            lock.unlock();
        }
    }

    /**
     * 异步回调接口
     * @param params params
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void orderNotify(Map<String, String> params) throws Exception {
        //验签
        if (alipayUtil.checkSignature(params)){
            //取出订单编号
            String orderNum = params.get("out_trade_no");
            //查询支付状态
            String tradeStatus = params.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus)){
                //对订单加锁
                RLock lock = redissonClient.getFairLock(OrderRedisKeyUtil.getOrderNumKey(orderNum));
                try {
                    if(lock.tryLock(10,TimeUnit.SECONDS)){
                        //查询订单信息
                        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
                        wrapper.eq("order_num",orderNum);
                        OrderInfo orderInfo = orderInfoMapper.selectOne(wrapper);
                        if (orderInfo!=null && Objects.equals(orderInfo.getOrderState(), OrderState.ORDER_STATE_NO_PAY)){
                            //查询支付时间
                            String payDate = params.get(AlipayUtil.PAY_TIME);
                            orderInfo.setOrderPayTime(payDate);
                            //修改支付状态
                            orderInfo.setOrderState(OrderState.ORDER_STATE_PAYED);
                            orderInfoMapper.updateById(orderInfo);
                            //生成当前产品进度表
                            //1.普通课程
                            if (Objects.equals(orderInfo.getTypes(), OrderState.ORDER_PRODUCT_TYPE_NORMAL)){
                                //体验卡课程
                                if (Objects.equals(orderInfo.getProductTypeId(), OrderState.PRODUCT_TYPE_ID_EXPERIENCE)){
                                    //调用创建方法
                                    createExpCard(orderInfo.getOrderNum(),orderInfo.getUserId());
                                }
                                //次卡课程
                                if (Objects.equals(orderInfo.getProductTypeId(), OrderState.PRODUCT_TYPE_ID_TIMES)){
                                    //调用创建方法
                                    createSubCard(orderInfo.getOrderNum(),orderInfo.getOrderCount(),orderInfo.getUserId());
                                }
                                //月卡课程
                                if (Objects.equals(orderInfo.getProductTypeId(), OrderState.PRODUCT_TYPE_ID_MONTHS)){
                                    //调用创建方法
                                    createMonCard(orderInfo.getOrderNum(),payDate,orderInfo.getOrderCount(),orderInfo.getUserId());
                                }
                                //终身卡课程
                                if (Objects.equals(orderInfo.getProductTypeId(), OrderState.PRODUCT_TYPE_ID_INFINITY)){
                                    //调用创建方法
                                    createLifeCard(orderInfo.getOrderNum(),orderInfo.getUserId());
                                }
                            }
                            //2.团课课程
                            if (Objects.equals(orderInfo.getTypes(), OrderState.ORDER_PRODUCT_TYPE_TEAM)){
                                Result<TeamProductByIdDTO> result = productClient.getByTeamProductId(orderInfo.getProductId());
                                if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
                                TeamProductByIdDTO teamProductByIdDTO = result.getData();
                                //调用创建方法
                                createTeaCard(orderInfo.getOrderNum(),teamProductByIdDTO.getHourCount(),orderInfo.getUserId());
                            }
                            //3.私教课
                            if (Objects.equals(orderInfo.getTypes(), OrderState.ORDER_PRODUCT_TYPE_COACH)){
                                //查询私教产品信息获取教练id
                                Result<PrivateProductByIdDTO> result = productClient.getByPrivateProductId(orderInfo.getProductId());
                                if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
                                PrivateProductByIdDTO privateProductByIdDTO = result.getData();
                                //判断教练状态
                                Result<Coach> coachResult = coachClient.getByCoachId(privateProductByIdDTO.getCoachId());
                                if (coachResult.getCode()!=200) throw new OrderException(coachResult.getCode(),coachResult.getMessage());
                                if (!Objects.equals(coachResult.getData().getCoachState(), CoachState.COACH_STATE_NORMAL))
                                    throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_COACH_STATE_WRONG);
                                //调用创建方法
                                createPriCard(orderInfo.getOrderNum(),privateProductByIdDTO.getCoachId(),orderInfo.getOrderCount(),orderInfo.getUserId());
                            }
                            //消息队列生成订单支付完成日志
                            Map<String, Object> logMap = new HashMap<>();
                            logMap.put("orderNum",orderInfo.getOrderNum());
                            logMap.put("storeId",orderInfo.getStoreId());
                            logMap.put("logUser",orderInfo.getUserName());
                            logMap.put("logTime",payDate);
                            logMap.put("logDesc","完成支付");
                            rabbitTemplate.convertAndSend("orderInfoNotify.log",logMap);
                        }
                    }else {
                        throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_SYSTEM_BUSY);
                    }
                }finally {
                    lock.unlock();
                }
            }
        }
    }

    /**
     * 生成次普通卡进度表
     * @param orderNum 订单编号
     */
    public void createExpCard(String orderNum,Integer userId){
        CreateExpCardForm form = new CreateExpCardForm();
        form.setOrderNum(orderNum);
        form.setUserId(userId);
        Result<?> result = progressClient.createExpCard(form);
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
    }

    /**
     * 生成次卡进度表
     * @param orderNum 订单编号
     * @param orderCount 数量
     */
    public void createSubCard(String orderNum,Integer orderCount,Integer userId){
        CreateSubCardForm form = new CreateSubCardForm();
        form.setOrderNum(orderNum);
        form.setOrderCount(orderCount);
        form.setUserId(userId);
        Result<?> result = progressClient.createSubCard(form);
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
    }

    /**
     * 生成月卡进度表
     * @param orderNum 订单编号
     * @param orderCount 数量
     */
    public void createMonCard(String orderNum,String payDate,Integer orderCount,Integer userId){
        CreateMonCardForm form = new CreateMonCardForm();
        form.setOrderNum(orderNum);
        form.setOrderCount(orderCount);
        form.setPayDate(payDate);
        form.setUserId(userId);
        Result<?> result = progressClient.createMonCard(form);
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
    }

    /**
     * 生成终身卡进度表
     * @param orderNum 订单编号
     */
    public void createLifeCard(String orderNum,Integer userId){
        CreateLifeCardForm form = new CreateLifeCardForm();
        form.setOrderNum(orderNum);
        form.setUserId(userId);
        Result<?> result = progressClient.createLifeCard(form);
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
    }

    /**
     * 生成团课进度表
     * @param orderNum 订单编号
     */
    public void createTeaCard(String orderNum,Integer hourCount,Integer userId){
        CreateTeaCardForm form = new CreateTeaCardForm();
        form.setOrderNum(orderNum);
        form.setHourCount(hourCount);
        form.setUserId(userId);
        Result<?> result = progressClient.createTeaCard(form);
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
    }

    /**
     * 生成私教课进度表
     * @param orderNum 订单编号
     */
    public void createPriCard(String orderNum,Integer coachId,Integer orderCount,Integer userId){
        CreatePriCardForm form = new CreatePriCardForm();
        form.setOrderNum(orderNum);
        form.setCoachId(coachId);
        form.setUserId(userId);
        form.setPricardCount(orderCount);
        Result<?> result = progressClient.createPriCard(form);
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
    }

    /**
     * 完成订单
     * @param orderNum 订单编号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeOrder(String orderNum) throws Exception {
        //查询订单信息
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",orderNum);
        OrderInfo orderInfo = orderInfoMapper.selectOne(wrapper);
        if (orderInfo == null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NOT_EXIST);
        if (Objects.equals(orderInfo.getOrderState(), OrderState.ORDER_STATE_DONE))
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NO_PAY);
        if (!Objects.equals(orderInfo.getOrderState(), OrderState.ORDER_STATE_PAYED))
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NO_PAY);
        //修改订单状态
        orderInfo.setOrderState(OrderState.ORDER_STATE_DONE);
        orderInfoMapper.updateById(orderInfo);
        //设置定时任务，15天用户未评价系统默认好评
        Map<String, Object> map = new HashMap<>();
        map.put("orderNum",orderInfo.getOrderNum());
        //转json字符串
        String orderNumXXL = JSONUtil.toJsonStr(map);
        //设置定时任务
        String xxlLoginAPI="http://192.168.90.27:9999/xxl-job-admin/login";
        String xxlAddJobAPI="http://192.168.90.27:9999/xxl-job-admin/jobinfo/add";
        HashMap<String, Object> loginParam = new HashMap<>();
        loginParam.put("userName", "admin");
        loginParam.put("password", "123456");
        HttpResponse httpResponse = HttpRequest.post(xxlLoginAPI).form(loginParam).execute();
        if(httpResponse.getStatus()!=200) {
            throw new Exception("登录失败");
        }
        Map<String, Object> addTaskParam = new HashMap<>();
        addTaskParam.put("jobGroup", 6);
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime executeTime = now.plusDays(15L);
        int year = executeTime.get(ChronoField.YEAR);
        int month = executeTime.get(ChronoField.MONTH_OF_YEAR);
        int day = executeTime.get(ChronoField.DAY_OF_MONTH);
        int hour=executeTime.get(ChronoField.HOUR_OF_DAY);
        int minute=executeTime.get(ChronoField.MINUTE_OF_HOUR);
        int second=executeTime.get(ChronoField.SECOND_OF_MINUTE);
        StringBuilder cron = new StringBuilder();
        cron.append(second);
        cron.append(" "+minute);
        cron.append(" "+hour);
        cron.append(" "+day);
        cron.append(" "+month);
        cron.append(" ?");
        cron.append(" "+year);
        addTaskParam.put("scheduleConf", cron.toString());
        addTaskParam.put("jobDesc", "系统自动评价");
        addTaskParam.put("author", "Zachary");
        addTaskParam.put("executorHandler", "orderExpire");
        addTaskParam.put("executorParam",orderNumXXL);//订单编号
        addTaskParam.put("scheduleType", "CRON");
        addTaskParam.put("executorRouteStrategy", "FIRST");
        addTaskParam.put("executorBlockStrategy", "SERIAL_EXECUTION");
        addTaskParam.put("glueType", "BEAN");
        addTaskParam.put("misfireStrategy","DO_NOTHING");
        addTaskParam.put("executorTimeout", "0");
        addTaskParam.put("executorFailRetryCount","0");
        addTaskParam.put("triggerStatus", 1);
        HttpResponse response = HttpRequest.post(xxlAddJobAPI).form(addTaskParam).execute();
        //生成日志信息
        Map<String, Object> logMap = new HashMap<>();
        logMap.put("orderNum",orderInfo.getOrderNum());
        logMap.put("storeId",orderInfo.getStoreId());
        logMap.put("logUser","管理员");
        logMap.put("logTime",DateUtil.format(new Date(System.currentTimeMillis()),"yyyy-MM-dd HH:mm:ss"));
        logMap.put("logDesc","完成订单");
        rabbitTemplate.convertAndSend("completeOrder.log",logMap);
    }

    @Override
    public PageInfo selectOrders(SelectOrdersParam param) {
        if (ObjectUtil.isEmpty(param.getPageNum()))
            param.setPageNum(1);
        if (ObjectUtil.isEmpty(param.getPageSize()))
            param.setPageSize(10);
        //条件查询
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(param.getOrderNum()))
            wrapper.like("order_num",param.getOrderNum());
        if (ObjectUtil.isNotEmpty(param.getProductName()))
            wrapper.like("product_name",param.getProductName());
        if (ObjectUtil.isNotEmpty(param.getUserName()))
            wrapper.like("user_name",param.getUserName());
        if (ObjectUtil.isNotEmpty(param.getOrderState()))
            wrapper.eq("order_state",param.getOrderState());
        //排序
        wrapper.orderByDesc("order_create_time");
        //查询分页
        Page<OrderInfo> page = new Page<>(param.getPageNum(), param.getPageSize());
        orderInfoMapper.selectPage(page,wrapper);
        //返回dto
        ArrayList<OrderInfoDto> orderInfoDtos = new ArrayList<>();
        for (OrderInfo record : page.getRecords()) {
            OrderInfoDto orderInfoDto = BeanUtil.toBean(record, OrderInfoDto.class);
            orderInfoDtos.add(orderInfoDto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(orderInfoDtos);
        return pageInfo;
    }

    /**
     * 商家分页查询订单
     * @param param param
     * @return PageInfo
     */
    @Override
    public PageInfo selectStoreOrders(SelectStoreOrdersParam param) {
        if (ObjectUtil.isEmpty(param.getPageNum()))
            param.setPageNum(1);
        if (ObjectUtil.isEmpty(param.getPageSize()))
            param.setPageSize(10);
        //获取场馆id
        Result<BusinessStoreByAccountIdDTO> result = businessClient.selBusinessStoreByAccountId(param.getBusinessId());
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
        BusinessStoreByAccountIdDTO storeDTO = result.getData();
        if (storeDTO==null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_STORE_NOT_EXIST);
        if (!Objects.equals(storeDTO.getStoreState(), BusinessState.STORE_STATE_NORMAL))
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_STORE_STATE_WRONG);
        //条件查询
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",storeDTO.getStoreId());
        if (ObjectUtil.isNotEmpty(param.getOrderNum()))
            wrapper.like("order_num",param.getOrderNum());
        if (ObjectUtil.isNotEmpty(param.getUserName()))
            wrapper.like("user_name",param.getUserName());
        if (ObjectUtil.isNotEmpty(param.getProductName()))
            wrapper.like("product_name",param.getProductName());
        if (ObjectUtil.isNotEmpty(param.getOrderState()))
            wrapper.eq("order_state",param.getOrderState());
        if (ObjectUtil.isNotEmpty(param.getOrderEvaluationState()))
            wrapper.eq("order_evaluation_state",param.getOrderEvaluationState());
        //排序
        wrapper.orderByDesc("order_create_time");
        //查询分页
        Page<OrderInfo> page = new Page<>(param.getPageNum(), param.getPageSize());
        orderInfoMapper.selectPage(page,wrapper);
        //返回dto
        ArrayList<OrderInfoDto> orderInfoDtos = new ArrayList<>();
        for (OrderInfo record : page.getRecords()) {
            OrderInfoDto orderInfoDto = BeanUtil.toBean(record, OrderInfoDto.class);
            orderInfoDtos.add(orderInfoDto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(orderInfoDtos);
        return pageInfo;
    }

    /**
     * 用户查询订单
     * @param param param
     * @return PageInfo
     */
    @Override
    public PageInfo selectUserOrders(SelectUserOrdersParam param) {
        //查询用户信息
        Result<UserInfoDto> result = userClient.getByUserId(param.getUserId());
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
        UserInfoDto userInfoDto = result.getData();
        if (!Objects.equals(userInfoDto.getUserState(), UserState.USER_ACCOUNT_STATE_NORMAL))
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_USER_STATE_WRONG);
        //条件查询
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(param.getOrderNum()))
            wrapper.like("order_num",param.getOrderNum());
        if (ObjectUtil.isNotEmpty(param.getProductName()))
            wrapper.like("product_name",param.getProductName());
        if (ObjectUtil.isNotEmpty(param.getOrderState()))
            wrapper.eq("order_state",param.getOrderState());
        if (ObjectUtil.isNotEmpty(param.getOrderEvaluationState()))
            wrapper.eq("order_evaluation_state",param.getOrderEvaluationState());
        //排序
        wrapper.orderByDesc("order_create_time");
        //查询分页
        Page<OrderInfo> page = new Page<>(param.getPageNum(), param.getPageSize());
        orderInfoMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        return pageInfo;
    }

    /**
     * 通过订单编号返回订单信息
     * @param orderNum 订单编号
     * @return OrderInfoDto
     */
    @Override
    public OrderInfoDto getByOrderNum(String orderNum) {
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",orderNum);
        OrderInfo orderInfo = orderInfoMapper.selectOne(wrapper);
        if (orderInfo==null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NOT_EXIST);
        return BeanUtil.toBean(orderInfo,OrderInfoDto.class);
    }

    /**
     * 修改订单评价状态
     * @param param 参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEvaluateState(UpdateEvaluateStateParam param) {
        //查询订单
        OrderInfo orderInfo = orderInfoMapper.selectById(param.getOrderNum());
        if (orderInfo==null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NOT_EXIST);
        if (!Objects.equals(orderInfo.getOrderState(), OrderState.ORDER_STATE_PAYED) && !Objects.equals(orderInfo.getOrderState(), OrderState.ORDER_STATE_DONE))
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NO_PAY);
        //修改状态
        orderInfo.setOrderEvaluationState(param.getEvaluateState());
        orderInfoMapper.updateById(orderInfo);
    }

    /**
     * 通过门店id查询订单集合
     * @param storeId 门店id
     * @return List<OrderInfoDto>
     */
    @Override
    public List<OrderInfoDto> listOrdersByStoreId(Integer storeId) {
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",storeId);
        List<OrderInfo> orderInfos = orderInfoMapper.selectList(wrapper);
        List<OrderInfoDto> orderInfoDtos = new ArrayList<>();
        for (OrderInfo orderInfo : orderInfos) {
            OrderInfoDto orderInfoDto = BeanUtil.toBean(orderInfo, OrderInfoDto.class);
            orderInfoDtos.add(orderInfoDto);
        }
        return orderInfoDtos;
    }

    /**
     * 获取一定时间段场馆的订单成交量和营业额
     * @param param 参数
     * @return DataDto
     */
    @Override
    public DataDto getDataByTime(GetDataParam param) {
        //判断时间是否合法
        LocalDateTime startTime = LocalDateTime.parse(param.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endTime = LocalDateTime.parse(param.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        if (startTime.isAfter(endTime)) throw new OrderException(OrderExceptionCode.TIME_START_AFTER_END);
        //查出信息
        LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInfo::getStoreId, param.getStoreId());
        //创建时间在这个区间内的
        wrapper.ge(OrderInfo::getOrderCreateTime, startTime);
        wrapper.le(OrderInfo::getOrderCreateTime, endTime);
        //且是已付款的
        wrapper.eq(OrderInfo::getOrderState, OrderState.ORDER_STATE_PAYED);
        List<OrderInfo> orderInfos = orderInfoMapper.selectList(wrapper);
        //计算收入
        BigDecimal income = new BigDecimal(0);
        for (OrderInfo orderInfo : orderInfos) {
            income = income.add(orderInfo.getOrderMoney());
        }
        DataDto dataDto = new DataDto();
        dataDto.setTurnover(income);
        dataDto.setOrder(orderInfos.size());
        return dataDto;
    }

    /**
     * 商家分页查询在学用户信息
     * @param param 参数
     * @return PageInfo
     */
    @Override
    public PageInfo selectStudyUser(SelectStudyUserParam param) {
        if (param.getCurrent()==null||param.getCurrent().equals(""))
            param.setCurrent(1);
        if (param.getSize()==null||param.getSize().equals(""))
            param.setSize(10);
        //通过商家账号id查询门店信息
        Result<BusinessStoreByAccountIdDTO> result = businessClient.selBusinessStoreByAccountId(param.getBusinessId());
        if (result.getCode()!=200) throw new OrderException(result.getCode(),result.getMessage());
        BusinessStoreByAccountIdDTO storeDto = result.getData();
        if (storeDto==null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_STORE_STATE_WRONG);
        //通过storeId查询该门店所有未完成订单
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",storeDto.getStoreId());
        wrapper.eq("order_state",OrderState.ORDER_STATE_PAYED);
        List<OrderInfo> orderInfos = orderInfoMapper.selectList(wrapper);
        if (orderInfos.size()==0) return null;
        //获取当前订单集合的用户id
        Set<Integer> userIds = new HashSet<>();
        //将userId存入set集合
        for (OrderInfo orderInfo : orderInfos) {
            userIds.add(orderInfo.getUserId());
        }
        //查询用户信息
        SelectUsersByIdsForm form = new SelectUsersByIdsForm();
        form.setUserIds(userIds);
        form.setCurrent(param.getCurrent());
        form.setSize(param.getSize());
        if (ObjectUtil.isNotEmpty(param.getRealName()))
            form.setRealName(param.getRealName());
        if (ObjectUtil.isNotEmpty(param.getUserPhone()))
            form.setUserPhone(param.getUserPhone());
        Result<PageInfo> usersByIds = userClient.selectUsersByIds(form);
        if (usersByIds.getCode()!=200) throw new OrderException(usersByIds.getCode(),usersByIds.getMessage());
        return usersByIds.getData();
    }
}
